package com.managertrade.service.impl;

import com.managertrade.dto.SysUserDTO;
import com.managertrade.dao.mysql.entity.SysRole;
import com.managertrade.dao.mysql.entity.SysUser;
import com.managertrade.dao.mysql.entity.SysUserRole;
import com.managertrade.dao.mysql.repository.SysRoleRepository;
import com.managertrade.dao.mysql.repository.SysUserRepository;
import com.managertrade.dao.mysql.repository.SysUserRoleRepository;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Transactional
public class SysUserServiceImpl implements SysUserService{
    @Resource
    private SysUserRepository sysUserRepository;

    @Autowired
    private SysUserRoleRepository sysUserRoleRepository;
    @Autowired
    private SysRoleRepository sysRoleRepository;
    @Override
    public Page<SysUserDTO> getUsers(Pageable pageable, String username) {
        Page<SysUser> user = sysUserRepository.findAll((root, query, cb) -> {
            if (StringUtils.hasText(username)) {
                return cb.like(root.get("username"), "%" + username + "%");
            }
            return cb.conjunction();
        }, pageable);
        // 使用 map 映射为 DTO
        return user.map(SysUserDTO::new);
    }

    @Override
    public SysUser findById(Long id) {
        return sysUserRepository.findById(id).orElse(null);
    }

    @Override
    public void save(SysUserDTO user) {
        System.out.println("Transaction active: " + TransactionSynchronizationManager.isActualTransactionActive());

        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(user,sysUser);
        //保存用户
         sysUserRepository.save(sysUser);
         //保存用户角色
        // 清空之前的用户角色（如果是更新操作时适用，可省略）
        // sysUserRoleRepository.deleteByUserId(sysUser.getId());
        SysUserRole userRole = new SysUserRole();
        userRole.setUserId(sysUser.getId());
        userRole.setRoleId(user.getRoleId());
        sysUserRoleRepository.save(userRole);

    }

    @Override
    public void deleteById(Long id) {
        sysUserRepository.deleteById(id);
    }

    @Override
    public void updateById(SysUserDTO user) {
        // 1️⃣ 查询数据库中的用户
        SysUser dbUser = sysUserRepository.findById(user.getId())
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        // 2️⃣ 更新用户信息
        dbUser.setNickname(user.getNickname());
        dbUser.setStatus(user.getStatus());
        if(!StringUtils.isEmpty(user.getPassword())){
            dbUser.setPassword(user.getPassword());
        }

        // 3️⃣ 删除旧角色（批量删除）
        List<SysUserRole> oldRoles = sysUserRoleRepository.findByUserId(user.getId());
        if(!oldRoles.isEmpty()){
            List<Long> ids = oldRoles.stream().map(SysUserRole::getId).collect(Collectors.toList());
            // 使用 Repository 的 @Modifying 方法删除
            sysUserRoleRepository.deleteByIds(ids);
        }

        // 4️⃣ 新增新角色
        SysUserRole newRole = new SysUserRole();
        newRole.setUserId(user.getId());
        newRole.setRoleId(user.getRoleId());
        sysUserRoleRepository.save(newRole);

        // 5️⃣ 保存用户
        sysUserRepository.save(dbUser);
    }

    @Override
    public void resetPassword(Long id) {
        SysUser dbUser = sysUserRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        dbUser.setPassword("123456"); // 这里也可以做加密处理
        sysUserRepository.save(dbUser);
    }

    @Override
    public Map<Long, SysRole> getUserRolesMap(List<Long> userIds) {
        // 查出 userId -> roleId 的关系
        List<SysUserRole> userRoles = sysUserRoleRepository.findByUserIdIn(userIds);
        // 提取所有 roleId
        Set<Long> roleIds = userRoles.stream()
                .map(SysUserRole::getRoleId)
                .collect(Collectors.toSet());
        // 查出所有角色
        Map<Long, SysRole> roleMap = sysRoleRepository.findAllById(roleIds).stream()
                .collect(Collectors.toMap(SysRole::getId, Function.identity()));

        // 构建 userId -> role 映射（这里只取一个角色，如果多角色请用 List<SysRole>）
        Map<Long, SysRole> result = new HashMap<>();
        for (SysUserRole ur : userRoles) {
            if (roleMap.containsKey(ur.getRoleId())) {
                result.put(ur.getUserId(), roleMap.get(ur.getRoleId()));
            }
        }
        return result;
    }
}
